<?php
/*
Plugin Name: Achievements
Plugin URI: http://metabiscuits.com
Description: Brings Achievements (similar to World of Warcraft or Xbox Live) to BuddyPress.
Version: 1.2
Requires at least: WPMU 2.8.2, BuddyPress 1.1
Tested up to: WPMU 2.8.6, BuddyPress 1.1.3
License: General Public License version 3 
Author: Paul Gibbs
Author URI: http://www.twitter.com/pgibbs
Site Wide Only: true


"Achievements" for BuddyPress
Copyright (C) 2009 Paul Gibbs

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License version 3 as published by
the Free Software Foundation.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see http://www.gnu.org/licenses/.


This software uses icons from the FAMFAMFAM "Silk" icon set used under
the http://creativecommons.org/licenses/by/3.0/ license (achievements_bullet.png,
cross.png, tick.png).
Visit them at http://www.famfamfam.com/lab/icons/silk/; thank you!


For developer documentation, please see devdoc.txt.
*/
define( 'DPA_VERSION', '1.2' );
define( 'DPA_DB_VERSION', '7' );

if ( !defined( 'DPA_SLUG' ) )
	define( 'DPA_SLUG', 'achievements' );

if ( !defined( 'DPA_SLUG_SUMMARY' ) )
	define( 'DPA_SLUG_SUMMARY', 'summary' );

require_once( 'dp-achievements/dp-achievements-notifications.php' );
require_once( 'dp-achievements/dp-achievements-classes.php' );
require_once( 'dp-achievements/dp-achievements-filters.php' );
require_once( 'dp-achievements/dp-achievements-templatetags.php' );
require_once( 'dp-achievements/dp-achievements-defaultachievements.php' );
require_once( 'dp-achievements/dp-achievements-cssjs.php' );
require_once( 'dp-achievements/dp-achievements-admin.php' );


/* Check that BuddyPress is loaded before Achievements */
function dpa_load_buddypress() {
	if ( function_exists( 'bp_core_setup_globals' ) )
		return true;

	/* Get the list of active sitewide plugins */
	$active_sitewide_plugins = maybe_unserialize( get_site_option( 'active_sitewide_plugins' ) );

	if ( !isset( $active_sidewide_plugins['buddypress/bp-loader.php'] ) )
		return false;

	if ( isset( $active_sidewide_plugins['buddypress/bp-loader.php'] ) && !function_exists( 'bp_core_setup_globals' ) ) {
		require_once( WP_PLUGIN_DIR . '/buddypress/bp-loader.php' );
		return true;
	}

	return false;
}
add_action( 'plugins_loaded', 'dpa_load_buddypress', 11 );

function dpa_install() {
	global $wpdb, $bp;

	if ( !empty( $wpdb->charset ) )
		$charset_collate = "DEFAULT CHARACTER SET $wpdb->charset";

	// Upgrade
	$version = get_site_option( 'dpa_db_version' );
	if ( $version !== false ) {

		switch ( $version ) {
			case '6': // version 1.0 + 1.1
				$wpdb->query( "RENAME TABLE {$wpdb->base_prefix}dpa_achievements_categories TO {$bp->achievements->table_categories}" );
				$wpdb->query( "RENAME TABLE {$wpdb->base_prefix}dpa_achievements_unlocked TO {$bp->achievements->table_unlocked}" );
				$wpdb->query( "RENAME TABLE {$wpdb->base_prefix}dpa_achievements TO {$bp->achievements->table_achievements}" );	

				// TODO: add note in documentation if there are existing custom achievements, they'll need to change their DB records appropiately.
				$wpdb->query( $wpdb->prepare( "ALTER TABLE {$bp->achievements->table_achievements} ADD COLUMN is_default int(1) NOT NULL" ) );
				$wpdb->query( $wpdb->prepare( "ALTER TABLE {$bp->achievements->table_achievements} ADD COLUMN is_special int(1) NOT NULL" ) );
				$wpdb->query( $wpdb->prepare( "ALTER TABLE {$bp->achievements->table_categories} ADD COLUMN is_default int(1) NOT NULL" ) );

				$wpdb->query( $wpdb->prepare( "UPDATE {$bp->achievements->table_achievements} SET is_default = 1, is_special = 0" ) );
				$wpdb->query( $wpdb->prepare( "UPDATE {$bp->achievements->table_categories} SET is_default = 1" ) );
				break;
		}

		update_site_option( 'dpa_db_version', DPA_DB_VERSION );
		do_action( 'dpa_after_upgrade' );
		return;
	}

	// Install
	$sql = array();
	$sql[] = "CREATE TABLE {$bp->achievements->table_achievements} (
					id bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
					category_id bigint(20) NOT NULL,
					short_name varchar(100) NOT NULL,
					nice_name varchar(100) NOT NULL,
					description longtext NOT NULL,
					points int(100) NOT NULL,
					active int(1) NOT NULL,
					is_default int(1) NOT NULL,
					is_special int(1) NOT NULL,
					KEY short_name (short_name)
				 ) {$charset_collate};";
	$sql[] = "CREATE TABLE {$bp->achievements->table_unlocked} (
					id bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
					achievement_id bigint(20) NOT NULL,
				  user_id bigint(20) NOT NULL,
					achieved_at DATETIME NOT NULL
				 ) {$charset_collate};";
	$sql[] = "CREATE TABLE {$bp->achievements->table_categories} (
					id bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
					category varchar(100) NOT NULL,
					is_default int(1) NOT NULL
				 ) {$charset_collate};";

	$categories = array( __( 'Blog', 'dpa' ), __( 'Friends', 'dpa' ), __( 'Groups', 'dpa' ), __( 'Messaging', 'dpa'), __( 'Profile', 'dpa' ) );
	foreach( $categories as $name ) {
		$sql[] = $wpdb->prepare( "INSERT INTO {$bp->achievements->table_categories} ( category, is_default ) VALUES ( %s, 1 );", $name );
	}

	require_once( ABSPATH . 'wp-admin/upgrade-functions.php' );
	dbDelta( $sql );
	$sql = array();

	$achievements = dpa_get_defaultachievements();
	foreach ( $achievements as $achievement ) {
		$category_id = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->achievements->table_categories} WHERE category = %s", $achievement['category'] ) );

		$sql[] = $wpdb->prepare( "INSERT INTO {$bp->achievements->table_achievements} ( category_id, short_name, nice_name, description, points, active, is_default, is_special ) VALUES ( %d, %s, %s, %s, %d, 1, 1, 0 );", $category_id, $achievement['short_name'], $achievement['name'], $achievement['description'], $achievement['points'] );
	}
	dbDelta( $sql );

	update_site_option( 'dpa_db_version', DPA_DB_VERSION );
	do_action( 'dpa_after_install' );
}

function dpa_setup_globals() {
	global $bp, $wpdb;

	/* For internal identification */
	$bp->achievements->id = 'achievements';

	$bp->achievements->slug = DPA_SLUG;
	$bp->achievements->slug_summary = DPA_SLUG_SUMMARY;
	$bp->achievements->table_achievements = $wpdb->base_prefix . 'dpa';
	$bp->achievements->table_unlocked = $wpdb->base_prefix . 'dpa_unlocked';
	$bp->achievements->table_categories = $wpdb->base_prefix . 'dpa_categories';
	$bp->achievements->format_notification_function = 'dpa_format_notifications';

	/* Register this in the active components array */
	$bp->active_components[$bp->achievements->slug] = $bp->achievements->id;
}
add_action( 'plugins_loaded', 'dpa_setup_globals' );
add_action( 'admin_menu', 'dpa_setup_globals' );

function dpa_check_installed() {
	if ( !is_site_admin() )
		return false;

	/* Need to check db tables exist, activate hook no-worky in mu-plugins folder. */
	if ( get_site_option( 'dpa_db_version' ) < DPA_DB_VERSION )
		dpa_install();
}
add_action( 'admin_menu', 'dpa_check_installed' );

function dpa_load_textdomain() {
	$locale = apply_filters( 'buddypress_locale', get_locale() );
	$mofile = WP_PLUGIN_DIR . "/achievements/dp-achievements/languages/achievements-$locale.mo";

	if ( file_exists( $mofile ) )
		load_textdomain( 'dpa', $mofile );
}
add_action ( 'plugins_loaded', 'dpa_load_textdomain', 5 );

add_action( 'dpa_after_upgrade', 'dpa_recalculate_userpoints' );
add_action( 'dpa_after_install', 'dpa_recalculate_userpoints' );

function dpa_setup_nav() {
	global $bp, $wpdb;

	/* Add 'Achievements' to the main navigation */
	bp_core_new_nav_item( array(
		'name' => __( 'Achievements', 'dpa' ),
		'slug' => $bp->achievements->slug,
		'screen_function' => 'dpa_screen',
		'default_subnav_slug' => $bp->achievements->slug_summary,
		'item_css_id' => $bp->achievements->id
	) );

	$achievements_link = $bp->loggedin_user->domain . $bp->achievements->slug . '/';

	/* Add the subnav items to the Achievements nav item */	
	bp_core_new_subnav_item( array(
		'name' => apply_filters( 'dpa_filter_achievement_category', __( 'Summary', 'dpa' ) ),
		'slug' => apply_filters( 'dpa_make_category_slug', $bp->achievements->slug_summary ),
		'parent_url' => $achievements_link,
		'parent_slug' => $bp->achievements->slug,
		'screen_function' => 'dpa_screen'
	) );

	$categories = wp_cache_get( 'dpa_distinct_categories', 'dpa' );
	if ( !$categories ) {
		$categories = $wpdb->get_col( $wpdb->prepare( "SELECT DISTINCT category FROM {$bp->achievements->table_achievements} as a, {$bp->achievements->table_categories} as c WHERE a.active = 1 AND c.id = a.category_id" ) );
		wp_cache_set( 'dpa_distinct_categories', $categories, 'dpa' );
	}

	foreach ( (array) $categories as $category_name ) {
		$slug = apply_filters( 'dpa_make_category_slug', $category_name );

		bp_core_new_subnav_item( array(
			'name' => apply_filters( 'dpa_filter_achievement_category', $category_name ),
			'slug' => $slug,
			'parent_url' => $achievements_link, 
			'parent_slug' => $bp->achievements->slug,
			'screen_function' => 'dpa_screen',
			'item_css_id' => "achievements-$slug"
		) );
	}

	if ( $bp->current_component == $bp->achievements->slug ) {
		if ( !bp_is_home() )
			$bp->bp_options_avatar = bp_core_fetch_avatar( array( 'item_id' => $bp->displayed_user->id, 'type' => 'thumb' ) );

		$bp->bp_options_title = __( 'Category', 'dpa' );
	}

	do_action( 'dpa_setup_nav' );
}
add_action( 'wp', 'dpa_setup_nav', 2 );
add_action( 'admin_menu', 'dpa_setup_nav', 2 );

/********************************************************************************
 * Business Functions
 *
 * Business functions are where all the magic happens in BuddyPress. They will
 * handle the actual saving or manipulation of information. Usually they will
 * hand off to a database class for data access, then return
 * true or false on success or failure.
 */

/*
TODO: DB table won't exist on first page load (via /wp-admin/).  As this is called on *every* page load,
can't to slow it down at all by checking URL or by SQL.  Any kind of "IF EXISTS" SQL syntax?
*/
function dpa_load_achievements() {
	global $bp, $wpdb;

	$achievements = $wpdb->get_col( $wpdb->prepare( "SELECT short_name FROM {$bp->achievements->table_achievements} WHERE active = 1" ) );	
	$unique_achievements = array();

  // Strips out anything after underscores (for ranked achievements).
	foreach ( (array) $achievements as $a ) { 
		$short_name = "dpa_register_$a"; 
		$i = strpos( $short_name, '_', strlen( 'dpa_register_' ) ); 
		if ( $i !== false )
			$short_name = substr( $short_name, 0, $i ); 

		$unique_achievements[] = $short_name; 
	}
	$unique_achievements = array_unique( $unique_achievements ); 

	foreach ( (array) $unique_achievements as $achievement ) {
		if ( function_exists( $achievement ) ) {
			do_action( 'dpa_beforeload_' . $achievement );
			call_user_func( $achievement );
			do_action( 'dpa_beforeload_' . $achievement );
		}
	}
}
add_action( 'plugins_loaded', 'dpa_load_achievements', 20 );

function dpa_update_userpoints( $user_id, $points=0 ) {
	$oldpoints = get_usermeta( $user_id, 'dpa_points' );
	update_usermeta( $user_id, 'dpa_points', apply_filters( 'dpa_filter_usermeta_points', $oldpoints ) + $points );
}

function dpa_update_achievement( $id, $action ) {
	global $bp, $wpdb;

	$sql = '';

	if ( 'enable' == $action )
		$sql = $wpdb->prepare( "UPDATE {$bp->achievements->table_achievements} SET active = 1 WHERE id = %d LIMIT 1", $id );
	elseif ( 'disable' == $action )
		$sql = $wpdb->prepare( "UPDATE {$bp->achievements->table_achievements} SET active = 0 WHERE id = %d LIMIT 1", $id );
	elseif ( 'save' == $action ) {
		if ( isset( $_REQUEST['achievement_category'] ) && isset( $_REQUEST['achievement_description'] ) && isset( $_REQUEST['achievement_points'] ) && isset( $_REQUEST['achievement_name'] ) ) {
			$sql = $wpdb->prepare( "UPDATE {$bp->achievements->table_achievements} SET category_id = %d, description = %s, points = %d, nice_name = %s WHERE id = %d LIMIT 1", $_REQUEST['achievement_category'], $_REQUEST['achievement_description'], $_REQUEST['achievement_points'], $_REQUEST['achievement_name'], $id );
		}
	}

	if ( empty( $sql ) || !$wpdb->query( $sql ) )
		bp_core_add_message( __( 'There was an error updating the database; please try again.', 'dpa' ), 'error' );
	else
		bp_core_add_message( __( 'Achievement details have been updated.', 'dpa' ) );
}

function dpa_recalculate_userpoints() {
	global $bp, $wpdb;

	if ( !is_site_admin() )
		return;

	define( 'DPA_CHECKING', 1 );
	$original_userid = $bp->loggedin_user->id;

	$user_ids = BP_Core_User::get_active_users( null, 1 );
	foreach ( $user_ids['users'] as $user ) {

		$achievements = $wpdb->get_col( $wpdb->prepare( "SELECT short_name FROM {$bp->achievements->table_achievements} WHERE active = 1 AND is_default = 1" ) );
		$unique_achievements = array();

	  // Strips out anything after underscores (for ranked achievements).
		foreach ( (array) $achievements as $achievement ) {
			$short_name = "dpa_handle_$achievement";
			$i = strpos( $short_name, '_', strlen( 'dpa_handle_' ) );
			if ( $i !== false )
				$short_name = substr( $short_name, 0, $i );

			$unique_achievements[] = $short_name;
		}
		$unique_achievements = array_unique( $unique_achievements );

		$bp->loggedin_user->id = $user->user_id;
		foreach ( (array) $unique_achievements as $achievement )
			call_user_func( $achievement );

		$sql = $wpdb->prepare( "SELECT SUM(points) FROM {$bp->achievements->table_unlocked} as u, {$bp->achievements->table_achievements} as a WHERE u.achievement_id = a.id AND a.active = 1 AND u.user_id = %d", $user->user_id );
		update_usermeta( $user->user_id, 'dpa_points', $wpdb->get_var( $sql ) );
	}

	do_action( 'dpa_recalculate_userpoints', $original_userid );
	$bp->loggedin_user->id = $original_userid;
}

function dpa_get_all_unlocked_achievements( $user_id, $limit=0, $category='' ) {
	global $wpdb, $bp;

	$sql = $wpdb->prepare( "SELECT a.id, achieved_at, category, description, active, is_special, nice_name, points, short_name FROM wp_dpa as a LEFT JOIN wp_dpa_unlocked as u ON a.id = u.achievement_id AND u.user_id = %d LEFT JOIN wp_dpa_categories as c ON a.category_id = c.id WHERE a.active = 1", $user_id );

	if ( $category )
		$sql .= $wpdb->prepare( " AND c.category = %s", $category );

	$sql .= " ORDER BY achieved_at DESC";

	if ( $limit )
		$sql .= " LIMIT {$limit}";

	return $wpdb->get_results( $sql );
}

function dpa_get_recent_achievements( $user_id, $limit=0, $category='' ) {
	global $wpdb, $bp;

	$sql = $wpdb->prepare( "SELECT a.id, achieved_at, category, description, active, is_special, nice_name, points, short_name FROM {$bp->achievements->table_achievements} as a, {$bp->achievements->table_categories} as c, {$bp->achievements->table_unlocked} as u WHERE a.active = 1 AND c.id = a.category_id AND u.achievement_id = a.id AND u.user_id = %d", $user_id );

	if ( $category )
		$sql .= $wpdb->prepare( " AND c.category = %s", $category );

	$sql .= " ORDER BY achieved_at DESC";

	if ( $limit )
		$sql .= " LIMIT {$limit}";

	return $wpdb->get_results( $sql );
}

function dpa_get_all_disabled_achievements( $limit=0, $category='' ) {
	global $wpdb, $bp;

	$sql = $wpdb->prepare( "SELECT a.id, category, description, active, is_special, nice_name, points, short_name FROM {$bp->achievements->table_achievements} as a, {$bp->achievements->table_categories} as c WHERE a.active = 0 AND c.id = a.category_id" );

	if ( $category )
		$sql .= $wpdb->prepare( " AND c.category = %s", $category );

	if ( $limit )
		$sql .= " LIMIT {$limit}";

	return $wpdb->get_results( $sql );
}

function dpa_get_all_enabled_achievements( $limit=0, $category='' ) {
	global $wpdb, $bp;

	$sql = $wpdb->prepare( "SELECT a.id, category, description, active, is_special, nice_name, points, short_name FROM {$bp->achievements->table_achievements} as a, {$bp->achievements->table_categories} as c WHERE a.active = 1 AND c.id = a.category_id" );

	if ( $category )
		$sql .= $wpdb->prepare( " AND c.category = %s", $category );

	if ( $limit )
		$sql .= " LIMIT {$limit}";

	return $wpdb->get_results( $sql );
}

function dpa_get_all_achievements( $limit=0, $category='' ) {
	global $wpdb, $bp;

	$sql = $wpdb->prepare( "SELECT a.id, category, description, active, is_special, nice_name, points, short_name FROM {$bp->achievements->table_achievements} as a, {$bp->achievements->table_categories} as c WHERE c.id = a.category_id" );

	if ( $category )
		$sql .= $wpdb->prepare( " AND c.category = %s", $category );

	if ( $limit )
		$sql .= " LIMIT {$limit}";

	return $wpdb->get_results( $sql );
}

function dpa_get_all_categories( $user_id, $category='' ) {
	global $wpdb, $bp;

	if ( $category ) {
		$category_names = array( $category );
	} else {

		$category_names = wp_cache_get( 'dpa_distinct_categories', 'dpa' );
		if ( !$category_names ) {
			$category_names = $wpdb->get_col( $wpdb->prepare( "SELECT DISTINCT category FROM {$bp->achievements->table_achievements} as a, {$bp->achievements->table_categories} as c WHERE a.active = 1 AND c.id = a.category_id" ) );
			wp_cache_set( 'dpa_distinct_categories', $category_names, 'dpa' );
		}
	}

	$categories = array();
	foreach ( (array) $category_names as $category ) {
		$categories[$category] = new stdClass;
		$categories[$category]->name = $category;
	}

	foreach ( (array) $category_names as $category ) {
		
		$sql = $wpdb->prepare( "SELECT COUNT(short_name) FROM {$bp->achievements->table_unlocked} as u, {$bp->achievements->table_achievements} as a, {$bp->achievements->table_categories} as c WHERE u.user_id = %d AND a.active = 1 AND u.achievement_id = a.id AND c.id = a.category_id AND c.category = %s", $user_id, $category );
		$categories[$category]->unlocked_count = (int) $wpdb->get_var( $sql );

		$sql = $wpdb->prepare( "SELECT COUNT(short_name) FROM {$bp->achievements->table_achievements} as a, {$bp->achievements->table_categories} as c WHERE a.active = 1 AND c.id = a.category_id AND c.category = %s", $category );
		$categories[$category]->total_count = (int) $wpdb->get_var( $sql );

		$categories[$category]->percentage = ( $categories[$category]->unlocked_count / $categories[$category]->total_count ) * 100;		
	}

	return array_values( $categories );
}

function dpa_get_overall_category( $user_id ) {
	global $wpdb, $bp;

	$overall = array();
	$overall[0] = new stdClass;
	$overall[0]->name = 'overall';

	$sql = $wpdb->prepare( "SELECT COUNT(short_name) FROM {$bp->achievements->table_unlocked} as u, {$bp->achievements->table_achievements} as a WHERE u.user_id = %d AND a.active = 1 AND u.achievement_id = a.id", $user_id );
	$overall[0]->unlocked_count = (int) $wpdb->get_var( $sql );

	$sql = $wpdb->prepare( "SELECT COUNT(id) FROM {$bp->achievements->table_achievements} WHERE active = 1" );
	$overall[0]->total_count = (int) $wpdb->get_var( $sql );
	$overall[0]->percentage = ( $overall[0]->unlocked_count / $overall[0]->total_count ) * 100;

	return $overall;
}


/********************************************************************************
 * Screen Functions
 *
 * Screen functions are the controllers of BuddyPress. They will execute when their
 * specific URL is caught. They will first save or manipulate data using business
 * functions, then pass on the user to a template file.
 */

function dpa_screen_filter_template( $located_template, $template_name ) {
	if ( !empty( $located_template ) )
		return $located_template;

	if ( $bp->current_component != $bp->achievements->slug )
		return false;

	if ( false !== strpos( $template_name[0], 'achievements_theme_' ) ) {
		$prefix = strlen( 'achievements_theme_' );
		$template_name = substr( $template_name[0], $prefix, strlen( $template_name[0] ) - $prefix );
		$template_path = WP_PLUGIN_DIR . "/achievements/dp-achievements/theme/$template_name";

		if ( file_exists( $template_path ) )
			return $template_path;
	}
	
	return false;
}
add_filter( 'bp_located_template', 'dpa_screen_filter_template', 10, 2 );

function dpa_screen() {
	global $bp, $is_member_page;

	if ( $bp->current_component == $bp->achievements->slug && !$is_member_page ) {
		bp_core_redirect( site_url() );
		return;
	}

	$page = bp_current_action();
	if ( $page == $bp->achievements->slug_summary ) {
		do_action( 'dpa_screen_summary' );
 		bp_core_load_template( 'achievements_theme_summary' );
  } else {
		do_action( 'dpa_screen_category', $page );
		bp_core_load_template( 'achievements_theme_category' );
	}
}

function dpa_screen_notification_settings() { 
	global $current_user;
	?>
	<table class="notification-settings" id="achievements-notification-settings">
		<tr>
			<th class="icon"></th>
			<th class="title"><?php _e( 'Achievements', 'dpa' ) ?></th>
			<th class="yes"><?php _e( 'Yes', 'dpa' ) ?></th>
			<th class="no"><?php _e( 'No', 'dpa' )?></th>
		</tr>
		<tr>
			<td></td>
			<td><?php _e( 'You unlock an achievement', 'dpa' ) ?></td>
			<td class="yes"><input type="radio" name="notifications[notification_dpa_unlock_achievement]" value="yes" <?php if ( !get_usermeta( $current_user->id, 'notification_dpa_unlock_achievement' ) || 'yes' == get_usermeta( $current_user->id, 'notification_dpa_unlock_achievement' ) ) { ?>checked="checked" <?php } ?>/></td>
			<td class="no"><input type="radio" name="notifications[notification_dpa_unlock_achievement]" value="no" <?php if ( get_usermeta( $current_user->id, 'notification_dpa_unlock_achievement' ) == 'no' ) { ?>checked="checked" <?php } ?>/></td>
		</tr>
		
		<?php do_action( 'dpa_screen_notification_settings' ); ?>
	</table>
<?php	
}
add_action( 'bp_notification_settings', 'dpa_screen_notification_settings' );


/********************************************************************************
 * Activity & Notification Functions
 *
 * These functions handle the recording, deleting and formatting of activity and
 * notifications for the user and for this specific component.
 */

function dpa_record_activity( $user_id, $content, $item_id, $component_action = 'new_achievement' ) {
	global $bp;

	if ( !function_exists( 'bp_activity_add' ) )
		return false;

	return bp_activity_add( array(
		'user_id' => $user_id,
		'content' => $content,
		'item_id' => $item_id,
		'component_name' => $bp->achievements->id,
		'component_action' => $component_action,
		'primary_link' => bp_core_get_userurl( $user_id )
	) );
}

function dpa_format_activity( $user_id, $achievement_id, $component_action = false ) {
	global $bp, $wpdb;

	if ( !$component_action )
		$component_action = 'new_achievement';

	$user_link = bp_core_get_userlink( $user_id );

	switch( $component_action ) {
		case 'new_achievement':
			$userdata = get_userdata( $user_id );

			$sql = $wpdb->prepare( "SELECT nice_name FROM {$bp->achievements->table_achievements} WHERE id = %d LIMIT 1", $achievement_id );
			$achievement_name = apply_filters( 'dpa_filter_achievement_nice_name', $wpdb->get_var( $sql ) );
			$achievement_link = sprintf( '<a href="%s">%s</a>', bp_core_get_userurl( $user_id ) . $bp->achievements->slug, $achievement_name );

			$stream_item = apply_filters( 'dpa_new_achievement_activity', sprintf( __( '%s unlocked achievement: %s', 'dpa' ), $user_link, $achievement_link ), $user_id, $achievement_id );
		break;
	}

	return apply_filters( 'dpa_format_activity', $stream_item, $user_id, $achievement_id, $component_action );
}

function dpa_register_activity_actions() {
	global $bp;
	
	if ( !function_exists( 'bp_activity_set_action' ) )
		return false;

	bp_activity_set_action( $bp->achievements->id, 'new_achievement', __( 'Achievement unlocked', 'dpa' ) );
	do_action( 'dpa_register_activity_actions' );
}
add_action( 'plugins_loaded', 'dpa_register_activity_actions' );

function dpa_format_notifications( $action, $item_id, $secondary_item_id, $total_items ) {
	global $bp, $wpdb;

	switch ( $action ) {
		case 'new_achievement':
			if ( 1 == $total_items ) {
				$sql = $wpdb->prepare( "SELECT nice_name FROM {$bp->achievements->table_achievements} WHERE id = %d LIMIT 1", $item_id );
				$achievement_name = apply_filters( 'dpa_filter_achievement_nice_name', $wpdb->get_var( $sql ) );		
				$user_url = bp_core_get_userurl( $secondary_item_id );

				return apply_filters( 'dpa_new_achievement_notification', '<a href="' . $user_url . $bp->achievements->slug. '">' . sprintf( __( 'Achievement unlocked: %s', 'dpa' ), $achievement_name ) . '</a>', $secondary_item_id, $item_id );

			} else {
				$user_url = bp_core_get_userurl( $bp->loggedin_user->id );

				return apply_filters( 'dpa_new_achievement_notification', '<a href="' . $user_url . $bp->achievements->slug. '">' . __( 'Achievements unlocked!', 'dpa' ) . '</a>', $secondary_item_id, $item_id );
			}
		break;
	}

	do_action( 'dpa_format_notifications', $action, $item_id, $secondary_item_id, $total_items );
	return false;
}

function dpa_screen_remove_notifications() {
	global $bp;

	if ( bp_is_home() )
		bp_core_delete_notifications_for_user_by_type( $bp->loggedin_user->id, $bp->achievements->slug, 'new_achievement' );
}
add_action( 'dpa_screen_summary', 'dpa_screen_remove_notifications' );
?>